package com.cykj.pos.controller.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.cykj.common.annotation.Log;
import com.cykj.common.core.controller.BaseController;
import com.cykj.common.core.domain.AjaxResult;
import com.cykj.common.core.domain.entity.SysDept;
import com.cykj.common.core.domain.entity.SysUser;
import com.cykj.common.core.page.TableDataInfo;
import com.cykj.common.enums.BusinessType;
import com.cykj.common.utils.poi.ExcelUtil;
import com.cykj.pos.domain.*;
import com.cykj.pos.domain.dto.SignatureDTO;
import com.cykj.pos.service.*;
import com.cykj.pos.util.HttpUtil;
import com.cykj.pos.util.LoginUserUtils;
import com.cykj.pos.util.PospUtils;
import com.cykj.system.mapper.SysDeptMapper;
import com.cykj.system.mapper.SysUserMapper;
import com.cykj.system.service.ISysDeptService;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;

/**
 * 意愿核身Controller
 *
 * @author 许晓龙
 * @date 2022-07-11
 */
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@RestController
@RequestMapping("/pos/nuclearbody")
public class PosV2IntendToNuclearBodyController extends BaseController {

    private final IBizIntendToNuclearBodyService iBizIntendToNuclearBodyService;
    private final IBizMerchantService bizMerchantService;
    private final IBizMicroInfoService bizMicroInfoService;
    private final IBizMerchantEntryService bizMerchantEntryService;
    private final IBizPosMachineService posMachineService;
    private final IBizMerchantInfoService iBizMerchantInfoService;
    private final SysUserMapper sysUserMapper;
    // 当前程序使用的accessToken
    private  String accessToken = "";
    private  String apiTicket = "";

    // accessToken的过期时效
    private  final int EXPIRED_SECONDS = 1200;
    // 当前最后更新accessToken的日期
    private Date latestDate = new Date();

    //获取 Access Token 请求方法：GET
    private String urlAccessToken = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/access_token";

    // 获取 SIGN ticket 请求方法：GET
    private String urlTicket = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket";

    //意愿核身识别结果查询接口请求方法：POST
    private String urlFace = "https://miniprogram-kyc.tencentcloudapi.com/api/server/getWillFaceResult?orderNo=";

    //获取faceID
    private String urlFaceID = "https://miniprogram-kyc.tencentcloudapi.com/api/server/getWillFaceId?orderNo=xxx";

    //获取 NONCE ticket
    private String urlNONCETicket = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket";


    @ApiOperation("获取faceId")
    @PostMapping("/getFaceID")
    public AjaxResult getFaceID(@RequestBody BizMerchantEntry bizMerchantEntry) {
        Long userId = LoginUserUtils.getLoginUserId(); //用户userID
        //订单号
        String orderNo = IdWorker.getIdStr();
        //获取系统商户编号
        //个人信息 要查询报件表 获取身份证 姓名
        BizMerchantInfo bizMerchantInfo = new BizMerchantInfo();
        bizMerchantInfo.setMerchantCode(bizMerchantEntry.getMerchantNo());
        BizMerchantInfo merchantInfo = iBizMerchantInfoService.getMerchantInfo(bizMerchantInfo);
        BizPosMachine bizPosMachine = posMachineService.selectPosBySnCode(bizMerchantEntry.getSn());
        AjaxResult ajaxResult = AjaxResult.success();
        Date now = new Date();
        WxFaceVersion wxFaceVersion = iBizIntendToNuclearBodyService.selectWxFaceVersion();
        String appid = wxFaceVersion.getAppid();
        String appSecret = wxFaceVersion.getAppSecret();
        //查询token和tickets
        Date updateTime = wxFaceVersion.getUpdateTime();
        String accessToken = wxFaceVersion.getAccessToken();
        String apiTicket = wxFaceVersion.getApiTicket();
        String NONCETicket = "";
        if((now.getTime() - updateTime.getTime()) < EXPIRED_SECONDS*1000 ) {
            //不请求  否则请求token tickets
            System.out.println("accessToken已经被更新过，" + accessToken);
            System.out.println("tickets，" + apiTicket );
        }else {
            String param = "app_id=" + appid + "&secret=" + appSecret + "&grant_type=" + "client_credential" + "&version=1.0.0";
            String result = HttpUtil.doGet(urlAccessToken, param);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String codeToken = jsonObject.getString("code");
            if (codeToken.equals("0")) {  //表示获取成功
                accessToken = jsonObject.getString("access_token");
                //https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket?app_id=xxx&access_token=xxx&type=SIGN&version=1.0.0
                //获取SIGN ticket
                String paramTicket = "app_id=" + appid + "&access_token=" + accessToken + "&type=SIGN&version=1.0.0";
                String result2 = HttpUtil.doGet(urlTicket, paramTicket);
                JSONObject obj = JSON.parseObject(result2);
                String codeTicket = obj.getString("code");
                if (codeTicket.equals("0")) {
                    JSONArray tickets = obj.getJSONArray("tickets");
                    for (int i = 0; i < tickets.size(); i++) {
                        JSONObject jsonObject1 = tickets.getJSONObject(i);
                        apiTicket = jsonObject1.getString("value");
                    }
                    wxFaceVersion.setAccessToken(accessToken);
                    wxFaceVersion.setApiTicket(apiTicket);
                    wxFaceVersion.setUpdateTime(now);
                    //更新
                    iBizIntendToNuclearBodyService.updatewxVersion(wxFaceVersion);
                }
            }
        }
        String createCode = getCharAndNumr(32);
        //生成签名
        List<String> stringList = new ArrayList<>();
        stringList.add(appid);
        stringList.add(String.valueOf(userId));
        stringList.add("1.0.0");
        stringList.add(createCode);
        String sign = sign(stringList,apiTicket);

        //再次生成签名 给前端用
        String createCode2 = getCharAndNumr(32);
        String paramNONCE = "app_id="+appid+"&access_token="+accessToken+"&type=NONCE&version=1.0.0"+"&user_id="+createCode2;
        String result4 = HttpUtil.doGet(urlNONCETicket, paramNONCE);
        JSONObject obj = JSON.parseObject(result4);
        String codeTicket = obj.getString("code");
        if (codeTicket.equals("0")) {
            JSONArray tickets = obj.getJSONArray("tickets");
            for (int i = 0; i < tickets.size(); i++) {
                JSONObject jsonObject1 = tickets.getJSONObject(i);
                NONCETicket = jsonObject1.getString("value");
            }
        }
        List<String> stringList1 = new ArrayList<>();
        stringList1.add(appid);
        stringList1.add(createCode2);
        stringList1.add("1.0.0");
        stringList1.add(createCode);
        System.out.println("-------------------------");
        System.out.println("appid="+appid+"userId="+createCode2+"version=1.0.0"+"nonce="+createCode+" ticket="+NONCETicket);
        String sign2 = sign(stringList1,NONCETicket);
        System.out.println("sign2"+sign2);
        //转为json字符
        JSONObject requestBody = new JSONObject();
        requestBody.put("appId", appid);
        requestBody.put("orderNo", orderNo);
        requestBody.put("nonce", createCode);
        requestBody.put("version", "1.0.0");
        requestBody.put("sign", sign);
        requestBody.put("name", merchantInfo.getLegalPersonName());
        requestBody.put("idNo", merchantInfo.getCertificateNo());
      /*  requestBody.put("name", "邢成格乐");
        requestBody.put("idNo", "152322199608012617");*/
        requestBody.put("userId", userId);
        ////liveService =1 标识仅活体，2 标识意愿性
        requestBody.put("liveService", "2");
        requestBody.put("willType", "0");
        requestBody.put("willLanguage", "0");
        List<WbFaceWillContent> willContentList = new ArrayList<>();
        WbFaceWillContent wbFaceWillContent = new WbFaceWillContent();
        wbFaceWillContent.setId("0");
        wbFaceWillContent.setQuestion("您本人是否已充分知悉将使用鑫收宝POS产品，知悉在激活时需支付"+bizPosMachine.getVar5()+"元激活服务费。如推销人员承诺其他事项，与鑫收宝无关？请回答:本人同意。");
        wbFaceWillContent.setAnswer("本人同意");
        willContentList.add(wbFaceWillContent);
        requestBody.put("willContentList",willContentList);
        String params = JSONObject.toJSONString(requestBody);
        String url = urlFaceID + orderNo;
        String result3 = HttpUtil.doPostxxl(url, params);
        JSONObject obj2 = JSON.parseObject(result3);
        if (obj2.getString("code").equals("0")){
            JSONObject result1 = obj2.getJSONObject("result");
            String faceId = result1.getString("faceId");
            ajaxResult.put("faceId",faceId);
            ajaxResult.put("orderNo",orderNo);
            ajaxResult.put("appId",appid);
            ajaxResult.put("version","1.0.0");
            ajaxResult.put("nonce",createCode);
            ajaxResult.put("userId",createCode2);
            SysUser user=sysUserMapper.selectUserById(userId);
            String licence=sysUserMapper.getLence(user.getDeptId());
            ajaxResult.put("keyLicence",licence);
            ajaxResult.put("sign",sign2);
        }else {
            return AjaxResult.error();
        }

        return ajaxResult;
    }

    /**
     * 签字确认
     * @return
     */
    @PostMapping("/signature")
    public AjaxResult signature(@RequestBody SignatureDTO signatureDTO){
        AjaxResult ajaxResult = AjaxResult.success();
        SignatureDTO signatureDTO1 =  posMachineService.selectPosMoneyInfo(signatureDTO.getMerchantNo());
        ajaxResult.put("data",signatureDTO1);
        return ajaxResult;
    }


    @PostMapping("/signTest")
    public AjaxResult signTest(@RequestBody TestSign testSign){
        AjaxResult ajaxResult = AjaxResult.success();
        //生成签名
        List<String> stringList = new ArrayList<>();
        stringList.add("IDA9gwK8");
        stringList.add(testSign.getOrderNo());
        stringList.add("1.0.0");
        stringList.add(testSign.getNonceStr());
        String sign = sign(stringList,"rZR2qOlsgUGfxpn7QvAznZh4lOmlB71D08qEQ32qBUCrPFbdrGpKqhNzhGPkHcWK");
        ajaxResult.put("sign",sign);
        return ajaxResult;
    }

    /**
     * 查询意愿核身列表
     */
    @PreAuthorize("@ss.hasPermi('pos:nuclearbody:list')")
    @GetMapping("/list")
    public TableDataInfo list(BizIntendToNuclearBody bizIntendToNuclearBody) {
        startPage();
        List<BizIntendToNuclearBody> list = iBizIntendToNuclearBodyService.queryList(bizIntendToNuclearBody);
        return getDataTable(list);
    }

    /**
     * 导出意愿核身列表
     */
    @PreAuthorize("@ss.hasPermi('pos:nuclearbody:export')")
    @Log(title = "意愿核身", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(BizIntendToNuclearBody bizIntendToNuclearBody) {
        List<BizIntendToNuclearBody> list = iBizIntendToNuclearBodyService.queryList(bizIntendToNuclearBody);
        ExcelUtil<BizIntendToNuclearBody> util = new ExcelUtil<BizIntendToNuclearBody>(BizIntendToNuclearBody.class);
        return util.exportExcel(list, "nuclearbody");
    }

    /**
     * 获取意愿核身详细信息
     */
    @PreAuthorize("@ss.hasPermi('pos:nuclearbody:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(iBizIntendToNuclearBodyService.getById(id));
    }

    /**
     * 新增意愿核身
     */
    @PreAuthorize("@ss.hasPermi('pos:nuclearbody:add')")
    @Log(title = "意愿核身", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody BizIntendToNuclearBody bizIntendToNuclearBody) {
        return toAjax(iBizIntendToNuclearBodyService.save(bizIntendToNuclearBody) ? 1 : 0);
    }

    /**
     * 修改意愿核身
     */
    @PreAuthorize("@ss.hasPermi('pos:nuclearbody:edit')")
    @Log(title = "意愿核身", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BizIntendToNuclearBody bizIntendToNuclearBody) {
        return toAjax(iBizIntendToNuclearBodyService.updateById(bizIntendToNuclearBody) ? 1 : 0);
    }

    /**
     * 删除意愿核身
     */
    @PreAuthorize("@ss.hasPermi('pos:nuclearbody:remove')")
    @Log(title = "意愿核身", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(iBizIntendToNuclearBodyService.removeByIds(Arrays.asList(ids)) ? 1 : 0);
    }


    /**
     * 随机字符串
     *
     * @param codeLength
     * @return
     */
    public static String createCode(int codeLength) {
        String code = "";
        for (int i = 0; i < codeLength; i++) {
            code += (int) (Math.random() * 9);
        }
        return code;
    }

    public static String dictSort(String str) {
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        return new String(chars);
    }


    public static String sign(List<String> values, String ticket) { //values传ticket外的其他参数
        if (values == null) {
            throw new NullPointerException("values is null");
        }
        values.removeAll(Collections.singleton(null));// remove null
        values.add(ticket);
        Collections.sort(values);

        StringBuilder sb = new StringBuilder();
        for (String s : values) {
            sb.append(s);
        }
        return Hashing.sha1().hashString(sb, Charsets.UTF_8).toString().toUpperCase();
    }


    /**
     * 方法1：生成随机数字和字母组合
     *
     * @param length
     * @return
     */

    public static String getCharAndNumr(int length) {

        Random random = new Random();

        StringBuffer valSb = new StringBuffer();

        String charStr = "0123456789abcdefghijklmnopqrstuvwxyz";

        int charLength = charStr.length();


        for (int i = 0; i < length; i++) {

            int index = random.nextInt(charLength);

            valSb.append(charStr.charAt(index));

        }

        return valSb.toString();

    }

}
